import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.*;

public class Test {

    public static void main(String[] args) throws Exception {
        TaskQueue taskQueue = new TaskQueue();

        Thread producer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                String task = "task_" + i;
                System.out.println("Producing " + task);
                taskQueue.addTask(task);
                try {
                    Thread.sleep(500); // 模拟生产任务的时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    String task = taskQueue.getTask();
                    System.out.println("Consuming " + task);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        consumer.start();
        Thread.sleep(1000); // 确保消费者先启动并等待任务
        producer.start();
        producer.join();
        consumer.join();
    }

}

class TaskQueue {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private Queue<String> queue = new LinkedList<>();

    public void addTask(String s) {
        lock.lock();
        try {
            queue.add(s);
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public String getTask() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                condition.await();
                // tryLock()类似，await()可以在等待指定时间后，如果还没有被其他线程通过signal()或signalAll()唤醒，可以自己醒来
                // if (condition.await(1, TimeUnit.SECONDS)) {
                //    System.out.println("被唤醒，继续检查任务队列");
                // }else {
                //     System.out.println("等待超时，继续检查任务队列");
                // }
            }
            return queue.remove();
        } finally {
            lock.unlock();
        }
    }
}
// signalAll() / signal() 只做一件事：
// 把等待队列里的线程挪到锁竞争队列（BLOCKED），让它们有资格抢锁；
// 真正执行仍需当前线程 unlock() 后，由这些被唤醒的线程去竞争锁，抢到才能继续。
// 所以：
// 唤醒 = 加入抢锁队列
// 解锁 = 真正放锁，让队列里的线程去竞争